.data

instruction:

.word 0


op:

.word 0

srcA:

.word 0

srcB:

.word 0

dest:

.word 0


.text


while:

// instruction = &mem[pc]

ld %r0, 2(%sp) //pc

ld %r1, 3(%sp) //mem

add2 %r0, %r1 // &mem[pc]

stl %r0, instruction // Store &mem[pc] at label instruction


// %r1 = op, dest

// %r2 = srcA

// %r3 = srcB


ld %r1, 0(%r0) //get value of instruction->op into op

stl %r1, op


ld %r1, 1(%r0) //get value of instruction->srcA into srcA

stl %r1, srcA


ld %r1, 2(%r0) //get value of instruction->srcB into srcB

stl %r1, srcB


ld %r1, 3(%r0) //get value of instruction->dest into dest

stl %r1, dest


ld %r0, 2(%sp) //pc

addi %r0, 4		// pc + 4

st %r0, 2(%sp) //pc = pc + 4


ldl %r1, op // op

movi %r2, 0x1FF // mov %r2, -1

ble %r1, %r2, while  // branch to while if op < 0

movi %r2, 0

ble %r1, %r2, case0 // branch to case0 if op == 0

movi %r2, 1

ble %r1, %r2, case1 // branch to case1 if op == 1

movi %r2, 2

ble %r1, %r2, case2 // branch to case2 if op == 2

movi %r2, 3

// From case3 onwards, the labels are too far from the current PC and
// therefore we will branch to a closer label and use a jmp which can
// jump with a higher offset.

ble %r1, %r2, case3_jmp // branch to case3_jmp if op == 3

movi %r2, 4

ble %r1, %r2, case4_jmp // branch to case4_jmp if op == 4

movi %r2, 5

ble %r1, %r2, case5_jmp // branch to case5_jmp if op == 5

movi %r2, 6

ble %r1, %r2, case6_jmp // branch to case6_jmp if op == 6

movi %r2, 7

ble %r1, %r2, case7_jmp // branch to case7_jmp if op == 7


jmp while //go back to start of while loop

case3_jmp:
  jmp case3
case4_jmp:
  jmp case4
case5_jmp:
  jmp case5
case6_jmp:
  jmp case6
case7_jmp:
  jmp case7

case0:


ldl %r0, srcA //srcA

ld %r1, 3(%sp) //mem

add2 %r0, %r1 // &mem[srcA]

ld %r0, 0(%r0) // r0 = mem[srcA]


ldl %r3, srcB //srcB

add2 %r3, %r1 //&mem[srcB]

ld %r3, 0(%r3) // r3 = mem[srcB]


sub2 %r0, %r3 // mem[srcA] - mem[srcB]

ldl %r3, dest //dest

add2 %r3, %r1 //&mem[dest]

st %r0, 0(%r3) // mem[dest] = mem[srcA] - mem[srcB]

jmp while


case1:

ldl %r0, srcA //srcA

ld %r1, 3(%sp) //mem

add2 %r0, %r1 //&mem[srcA]

ld %r0, 0(%r0) // r0 = mem[srcA]



slri %r0, 1 // mem[srcA] >> 1

ldl %r3, dest //dest

add2 %r3, %r1 //&mem[dest]

st %r0, 0(%r3) // mem[dest] = mem[srcA] >> 1


jmp while


case2:


ldl %r0, srcA //srcA

ld %r1, 3(%sp) //mem

add2 %r0, %r1 // &mem[srcA]

ld %r0, 0(%r0) // r0 = mem[srcA]


ldl %r3, srcB //srcB

add2 %r3, %r1 // &mem[srcB]

ld %r3, 0(%r3) // r3 = mem[srcB]

nor2 %r0, %r3 // ~(mem[srcA] | mem[srcB])


ldl %r3, dest //dest

add2 %r3, %r1 //&mem[dest]

st %r0, 0(%r3) // mem[dest] = ~( mem[srcA] | mem[srcB])


jmp while


case3:


ld %r1, 3(%sp) //mem


ldl %r3, srcB //srcB

add2 %r3, %r1 // & mem[srcB]

ld %r3, 0(%r3) // mem[srcB]

mov %r0, %r3 // temp = mem[srcB]


ldl %r3, srcA //srcA

add2 %r3, %r1 // &mem[srcA]

ld %r3, 0(%r3) // r3 = mem[srcA]

add2 %r3, %r1 //&mem[mem[srcA]]

ld %r3, 0(%r3) // r3 = mem[mem[srcA]]



ldl %r2, dest //dest

add2 %r2, %r1 //&mem[dest]

st %r3, 0(%r2) // mem[dest] = mem[mem[srcA]]


ldl %r3, srcA //srcA

add2 %r3, %r1 // &mem[srcA]

ld %r3, 0(%r3) // r3 = mem[srcA]

add2 %r3, %r1 // &mem[mem[srcA]]

st %r0, 0(%r3) // mem[mem[srcA]] = temp


jmp while


case4:


ldl %r0, srcA //srcA

ld %r1, 3(%sp) //mem

add2 %r0, %r1  // &mem[srcA]

ld %r0, 0(%r0) // r0 = mem[srcA]


ldl %r3, dest //dest

add2 %r3, %r1 //&mem[dest]

in %r2, %r0 //r2 = value from channel

st %r2, 0(%r3) // mem[dest] = r2

jmp while


case5:


ldl %r0, srcA //srcA

ld %r1, 3(%sp) //mem

add2 %r0, %r1 // &mem[srcA]

ld %r0, 0(%r0) // r0 = mem[srcA]


ldl %r3, srcB // srcB

add2 %r3, %r1 //&mem[srcB]

ld %r3, 0(%r3) //r3 = mem[srcB]


out %r0, %r3 // put value in %r0 to channel %r3


jmp while


case6:


ld %r1, 3(%sp) // r1 = mem


ld %r0, 2(%sp) //r0 = pc

ldl %r3, dest //dest

add2 %r3, %r1 //&mem[dest]

st %r0, 0(%r3) // mem[dest] = pc


ldl %r0, srcA //srcA

add2 %r0, %r1 // &mem[srcA]

ld %r0, 0(%r0) // r0 = mem[srcA]


movi %r2, 0x1FF // r2 = -1


ble %r0, %r2, ifstmt

jmp while


ifstmt:

ldl %r3, srcB //srcB

add2 %r3, %r1 //&mem[srcB]

ld %r3, 0(%r3) // r3 = mem[srcB]


st %r3, 2(%sp) //pc = mem[srcB]

jmp while


case7:

ld %rv, 2(%sp) // return value = pc

halt
return
